home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / rbbs / rbbs_mpl.zip / ANSIED.BAS < prev    next >
BASIC Source File  |  1992-07-05  |  47KB  |  1,402 lines

  1. ' $linesize:132
  2. ' $title: 'ANSIED.BAS'
  3. '*
  4. '*  ANSIED v2.44a  by Tom Collins 
  5. '*---------------------------------------------------------------------------
  6. '*  Full Screen Text Editor for RBBS-PC
  7. '*  QuickBASIC v4.5 Version
  8. '*  02-16-91
  9. '*
  10. '*  v2.1xx ... made it work with RBBS v17
  11. '*  v2.2 ..... fixed some inconsistincies in the code as to # of lines in msg.
  12. '*             Some of the code thought 99 was length, some thought 100.
  13. '*  v2.3 ..... let it work with quoted reply.  No more REDIM of ZOutTxt$
  14. '*  v2.4 ..... removed tabs, margins code to be smaller
  15. '*  v2.41..... fixed bug with loss of bold attribute occasionally
  16. '*  v2.42..... made it work as a v17.3 subroutine.  Added block delete.
  17. '*  v2.43..... Added to: and from:.  Made cursor keys work locally.
  18. '*  v2.43a.... Stupid little bugs fixed
  19. '*  v2.44..... Fixed bugs, added ^T, Import, Subject, ASM functions
  20. '*  v2.44a.... Wordwrap/reflow bug fixed.  Arrows work in del.  Lines renum.
  21. '*
  22. '*  Returns:
  23. '*  ZSubParm  =  1 - Save Message
  24. '*            =  2 - Abort Message
  25. '*            = -1 - Dropped Carrier
  26. '*            = -2 - Sleep Disconnect
  27. '*
  28. '* Compile with:
  29. '*   BC C:\RBBSARCS\ANSIED.BAS /O/T/C:512;
  30. '*   
  31. '* Modifications to 2.44a by: Steve Stevens
  32. '* If you Like 'em let me know!
  33. '*       FIDONET 1:376/102                      RBBSNet 8:927/2
  34.  
  35.  
  36. 100   CONST RedFore = 31
  37.       CONST GreenFore = 32
  38.       CONST YellowFore = 33
  39.       CONST BlueFore = 34
  40.       CONST MagentaFore = 35
  41.       CONST CyanFore = 36
  42.       CONST WhiteFore = 37
  43.       CONST BlueBack = 44
  44.       CONST DefaultColor = 99
  45.       CONST DefaultBold = 99
  46.  
  47. 110   CONST ESCKey = 27
  48.       CONST BackspKey = 8
  49.       CONST OtherBackspKey = 127
  50.       CONST CarrRet = 13
  51.       CONST WordLeftKey = 1          ' Ctrl-A
  52.       CONST ReformTextKey = 2        ' Ctrl-B
  53.       CONST PageDownKey = 3          ' Ctrl-C
  54.       CONST ColRightKey = 4          ' Ctrl-D
  55.       CONST LineUpKey = 5            ' Ctrl-E
  56.       CONST WordRightKey = 6         ' Ctrl-F
  57.       CONST CharDeleteKey = 7        ' Ctrl-G
  58.       CONST TabKey = 9               ' Ctrl-I <- Tab Key Support
  59.       CONST EndSessionKey = 11       ' Ctrl-K
  60.       CONST HelpKey = 14             ' Ctrl-N
  61.       CONST ReflowTextKey = 15       ' Ctrl-O
  62.       CONST RepaintKey = 16          ' Ctrl-P
  63.       CONST PageUpKey = 18           ' Ctrl-R
  64.       CONST ColLeftKey = 19          ' Ctrl-S
  65.       CONST DeleteWordRightKey = 20  ' Ctrl-T
  66.       CONST ToggleINSKey = 22        ' Ctrl-V
  67.       CONST HomeKey = 23             ' Ctrl-W
  68.       CONST LineDownKey = 24         ' Ctrl-X
  69.       CONST LineDeleteKey = 25       ' Ctrl-Y
  70.       CONST EndKey = 26              ' Ctrl-Z
  71.  
  72.       CONST BlankLine$ = ""
  73. 119   CONST Version$ = "v2.44a"      ' v2.44a
  74.  
  75.       DEFINT A-Z
  76.  
  77. 120   COMMON SHARED /Ansied/ CurrentRow, CurrentCol, TopLine
  78.       COMMON SHARED /Ansied/ OldColour, IsBold, InsertMode
  79.       COMMON SHARED /Ansied/ SoftSpace$
  80.       COMMON SHARED /Ansied/ BlockDelActive, MsgLockLines
  81.       COMMON SHARED /Ansied/ BlockLine1, BlockLine2
  82.       COMMON SHARED /Ansied/ MsgTo$, MsgSubj$
  83.  
  84. ' $INCLUDE: 'RBBS-VAR.MOD'
  85.  
  86. '      REDIM ZOutTxt$(99)     '<-- Needed to add this,
  87. '      REDIM ZUserIn$(10)      '<-- And this for some strange reason.
  88.  
  89. '*  AnsiEd
  90. '*----------------------------------------------------------------------------
  91. '*  Main full-screen editor routine
  92. '*
  93. '*
  94.       SUB Ansied (T$, S$, L%) STATIC
  95.       '*
  96.       '* ZworkAra$() holds what's currently on the user's screen.
  97.       '* 24 Lines: ZWorkAra$(1) = Menu, Bottom Line = "Line 25"
  98.       '*
  99.  
  100. 500  REDIM ZWorkAra$(24)
  101.       '*
  102.       '* TopLine is the index into the ZOutTxt$() array that
  103.       '* corresponds to the top of the displayed image, i.e.
  104.       '* what's on line 3 of the user's screen.
  105.       '*
  106.       '*   1,12,23,34,45,56,78
  107.       '*
  108.       TopLine = 1
  109.       SoftSpace$ = CHR$(250)
  110.       InsertMode = ZTrue
  111.       ZLineFeed$ = CHR$(10)
  112.       BlockDelActive = ZFalse
  113.       HiLiteSave = ZHiLiteOff
  114.       ZHiLiteOff = ZFalse
  115.       UseTputSave = ZUseTput
  116.       ZUseTput = ZFalse
  117.       MsgLockLines = L%
  118.       MsgTo$ = T$
  119.       CALL NameCaps(MsgTo$)
  120.  
  121.       MsgSubj$ = S$
  122.       YY$ = ""
  123.       IF LEFT$(MsgSubj$, 3) = "(R)" THEN
  124.          YY$ = "(R)"
  125.          MsgSubj$ = MID$(MsgSubj$, 4)
  126.       END IF
  127.       CALL NameCaps(MsgSubj$)
  128.       MsgSubj$ = YY$ + MsgSubj$
  129.  
  130.       '*
  131.       '* Initialize the screen
  132.       '*
  133. 510   CALL ClearScreen
  134.       CALL UpdateStatusLine(1)
  135.       CALL DisplayKeys
  136.       CALL MoveCursor(3, 1)
  137.       '*
  138.       '* Remove ANSI sequences from the quoted lines
  139.       '*
  140.       IF ZLinesInMsg > 88 THEN
  141.          ZLinesInMsg = 88
  142.       END IF
  143.       IF ZMaxMsgLines > 98 THEN
  144.          ZMaxMsgLines = 98
  145.       END IF
  146.       IF ZLinesInMsg > ZMaxMsgLines THEN
  147.          ZLinesInMsg = ZMaxMsgLines
  148.       END IF
  149.       FOR I = ZLinesInMsg + 1 TO 99
  150.          ZOutTxt$(I) = BlankLine$
  151.       NEXT
  152.       IF ZLinesInMsg <> 0 THEN
  153.          FOR I = 1 TO ZLinesInMsg
  154.             CALL UnString(ZOutTxt$(I), "")
  155.          NEXT
  156.          J = ZLinesInMsg \ 11
  157.          IF ZLinesInMsg MOD 11 = 0 THEN
  158.            J = J - 1
  159.          END IF
  160.          TopLine = J * 11 + 1
  161.          J = ZLinesInMsg - TopLine
  162.          CALL MoveCursor(J + 5, 1)
  163.       END IF
  164.       CALL UpdateScreen
  165. 'CALL UpdatePos
  166.       '*
  167.       '* Run the Editor
  168.       '*
  169. 520   WHILE 1
  170.  
  171.          CALL GetChar(B$): GOSUB 740
  172.          KeyPressed = ASC(B$)
  173.          CALL SaveCursor(RowSave, ColSave)
  174.  
  175.          '*
  176.          '* Look for an ANSI escape sequence after an ESC
  177.          '*
  178. 525      IF KeyPressed = ESCKey THEN            ' v2.44a
  179.             CALL GetChar(B$): GOSUB 740
  180.             IF B$ = "[" THEN                    ' ANSI sequence
  181.                CALL GetChar(B$): GOSUB 740
  182.                IF B$ = "C" THEN
  183.                   KeyPressed = ColRightKey
  184.                ELSEIF B$ = "D" THEN
  185.                   KeyPressed = ColLeftKey
  186.                ELSEIF B$ = "A" THEN
  187.                   KeyPressed = LineUpKey
  188.                ELSEIF B$ = "B" THEN
  189.                   KeyPressed = LineDownKey
  190.                END IF
  191.             END IF
  192.          END IF
  193.  
  194.          Index = CurrentRow + TopLine - 3
  195.  
  196.          IF BlockDelActive OR Index <= MsgLockLines OR Index > ZMaxMsgLines THEN
  197. 530         SELECT CASE KeyPressed
  198.                CASE CarrRet
  199.                   IF BlockDelActive THEN
  200.                      BlockDelActive = ZFalse
  201.                      BlockLine2 = Index
  202.                      IF BlockLine2 < BlockLine1 THEN
  203.                         SWAP BlockLine1, BlockLine2
  204.                      END IF
  205.                      IF BlockLine1 <= MsgLockLines THEN
  206.                         BlockLine1 = MsgLockLines + 1
  207.                      END IF
  208.                      IF BlockLine2 > ZMaxMsgLines THEN
  209.                         BlockLine2 = ZMaxMsgLines
  210.                      END IF
  211.                      K = 0
  212.                      FOR I = BlockLine2 + 1 TO 99
  213.                         ZOutTxt$(BlockLine1 + K) = ZOutTxt$(I)
  214.                         K = K + 1
  215.                      NEXT I
  216.                      WHILE BlockLine1 + K <= 99
  217.                         ZOutTxt$(BlockLine1 + K) = BlankLine$
  218.                         K = K + 1
  219.                      WEND
  220.                      CALL UpdateScreen
  221.                      CALL UpdateStatusLine(2)
  222.                      CALL MoveCursor(BlockRow, BlockCol)
  223. 'CALL UpdatePos
  224.                   END IF
  225.                   KeyPressed = 255
  226.  
  227. 540            CASE ESCKey
  228.                   IF BlockDelActive THEN
  229.                      BlockDelActive = ZFalse
  230.                      CALL ClearScreen        ' <-- Added when user cancells
  231.                      CALL UpdateScreen       ' Block Delete the "highlighted"
  232.                      CALL UpdateStatusLine(1)
  233.                      CALL UpdateStatusLine(2)
  234.                      CALL MoveCursor(BlockRow, BlockCol)
  235. 'CALL UpdatePos                               ' Letters are changed back.
  236.                      KeyPressed = 255
  237.                   END IF
  238.  
  239.                CASE LineUpKey, LineDownKey, PageDownKey, PageUpKey, TabKey
  240.                   '*
  241.                   '* Up and Down get passed on
  242.                   '*
  243.                CASE ELSE
  244.                   '*
  245.                   '* Ignore the key
  246.                   '*
  247.                   KeyPressed = 255
  248.  
  249.             END SELECT
  250.          END IF
  251.  
  252. 560      SELECT CASE KeyPressed
  253.             CASE ESCKey,EndSessionKey    'Pe 03/17/92
  254.                '*
  255.                '* User wants to see main menu
  256.                '*
  257.                CALL DisplayMainMenu
  258.                CALL MoveCursor(RowSave, ColSave)
  259.                CALL GetChar(B$): GOSUB 740
  260.                CALL AllCaps(B$)                                        'RT062992
  261.                IF B$ = "D" THEN
  262.                   BlockDelActive = ZTrue
  263.                   BlockLine1 = RowSave + TopLine - 3
  264.                   BlockCol = ColSave
  265.                   BlockRow = RowSave
  266.                   CALL EraseToEOL(1, 1)
  267.                   ' v2.44a
  268.                   CALL PutScreen("Delete Block: Press ENTER on Last Line to Delete, or ESC Twice to Quit", DefaultColor, DefaultBold)
  269.                   BlockLine2 = 0
  270.   CALL MoveCursor(RowSave, 1)                                'SM070501
  271.    Index = (RowSave) + (Topline - 3)
  272.     CALL Putscreen(ZOutTxt$(Index),RedFore,ZFalse)
  273.                ELSE
  274.                   CALL MenuCommand(B$): GOSUB 740
  275.                END IF
  276.      CALL MoveCursor(RowSave, ColSave)
  277. 'CALL UpdatePos
  278.  
  279. 570         CASE LineUpKey
  280.                '*
  281.                '* Move the current cursor position up one line
  282.                '*
  283.                IF CurrentRow > 3 THEN
  284.                   CALL MoveCursor(CurrentRow - 1, CurrentCol)
  285.                ELSE
  286.                   IF TopLine <> 1 THEN
  287.                      TopLine = TopLine - 11
  288.                      CALL MoveCursor(CurrentRow + 10, CurrentCol)
  289.                      CALL UpdateScreen
  290.                   END IF
  291.                END IF
  292. '*
  293. '* Un-Highlights lines to be deleted
  294. '* Steve
  295. IF BlockDelActive THEN
  296. ' CALL SaveCursor(SaveRow, SaveCol)
  297.   Index = (CurrentRow + 1) + (Topline - 3)
  298.     CALL MoveCursor(CurrentRow,1)                            'SM070501
  299.     CALL Putscreen(ZOutTxt$(Index), YellowFore,ZTrue)
  300.      CALL MoveCursor(SaveRow, SaveCol)
  301. END IF
  302. 'CALL UpdatePos
  303.  
  304. 580         CASE LineDownKey
  305.                '*
  306.                '* Move the current cursor position down one line
  307.                '*
  308.                IF CurrentRow < 19 THEN
  309.                   CALL MoveCursor(CurrentRow + 1, CurrentCol)
  310.                ELSEIF BlockDelActive THEN
  311.                 CALL PutScreen(CHR$(7),RedFore,ZFalse)
  312.                ELSE
  313.                   IF NOT TopLine = 78 THEN
  314.                      TopLine = TopLine + 11
  315.                      CALL MoveCursor(CurrentRow - 10, CurrentCol)
  316.                      CALL UpdateScreen
  317.                   END IF
  318.                END IF
  319. '*
  320. '* Highlight lines to be delete
  321. '*        Steve
  322. IF BlockDelActive THEN
  323. ' CALL SaveCursor(SaveRow, SaveCol)
  324.    Index = (CurrentRow) + (Topline - 3)
  325. '    CALL MoveCursor(CurrentRow,1)
  326.       CALL Putscreen(ZOutTxt$(Index),RedFore,ZFalse)
  327.        CALL MoveCursor(CurrentRow, 1)
  328. END IF
  329. 'CALL UpdatePos
  330. 590         CASE ColLeftKey
  331.                '*
  332.                '* Move the current cursor left one column
  333.                '*
  334.                IF CurrentCol > 1 THEN
  335.                   CALL MoveCursor(CurrentRow, CurrentCol - 1)
  336. 'CALL UpdatePos
  337.                END IF
  338.  
  339. 595         CASE TabKey    ' <- Tab Key Support here..
  340.                '*
  341.                '* Tab 8 Spaces
  342.                '*
  343.                IF CurrentCol < 72 THEN
  344.                 CALL MoveCursor(CurrentRow, CurrentCol + 8)
  345. 'CALL UpdatePos
  346.                END IF
  347.  
  348. 600         CASE ColRightKey
  349.                '*
  350.                '* Move the current cursor right one column
  351.                '*
  352.                IF CurrentCol < 79 THEN
  353.                   CALL MoveCursor(CurrentRow, CurrentCol + 1)
  354. 'CALL UpdatePos
  355.                END IF
  356.  
  357. 610         CASE WordRightKey, WordLeftKey
  358.                '*
  359.                '* Move the current cursor one word
  360.                '*
  361.                I = KeyPressed - WordLeftKey
  362.                NewCol = CurrentCol
  363.                CALL FindWord(ZOutTxt$(Index), I, NewCol)
  364.                IF NewCol > 79 THEN
  365.                   NewCol = 79
  366.                END IF
  367.                CALL MoveCursor(CurrentRow, NewCol)
  368. 'CALL UpdatePos
  369.  
  370. 620         CASE DeleteWordRightKey
  371.                '*
  372.                '* Delete the current word
  373.                '*
  374.                I = CurrentCol
  375.                L = LEN(ZOutTxt$(Index))
  376.                CALL FindWord(ZOutTxt$(Index), 1, I)
  377.                IF I > CurrentCol THEN
  378.                   YY$ = MID$(ZOutTxt$(Index), I)
  379.                   MID$(ZOutTxt$(Index), CurrentCol) = YY$
  380.                   ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), L - (I - CurrentCol))
  381.                   CALL PutScreen(YY$, YellowFore, ZTrue)
  382.                   CALL EraseToEOL(RowSave, CurrentCol)
  383.                   CALL MoveCursor(RowSave, ColSave)
  384. 'CALL UpdatePos
  385.                END IF
  386.  
  387. 630         CASE HomeKey
  388.                '*
  389.                '* Move cursor to the start of the line
  390.                '*
  391.                CALL MoveCursor(CurrentRow, 1)
  392. 'CALL UpdatePos
  393.  
  394. 640         CASE EndKey
  395.                '*
  396.                '* Move cursor to the end of the line
  397.                '*
  398.                NewCol = LEN(ZOutTxt$(Index)) + 1
  399.                IF NewCol > 79 THEN
  400.                   NewCol = 79
  401.                END IF
  402.                CALL MoveCursor(CurrentRow, NewCol)
  403. 'CALL UpdatePos
  404.  
  405. 650         CASE PageDownKey
  406.                '*
  407.                '* Move the display one page down
  408.                '*
  409.                TopLine = TopLine + 22
  410.                IF TopLine > 78 THEN
  411.                   TopLine = 78
  412.                END IF
  413.                CALL UpdateScreen
  414.  
  415. 660         CASE PageUpKey
  416.                '*
  417.                '* Move the display one page up
  418.                '*
  419.                TopLine = TopLine - 22
  420.                IF TopLine < 1 THEN
  421.                   TopLine = 1
  422.                END IF
  423.                CALL UpdateScreen
  424.  
  425. 670         CASE LineDeleteKey
  426.                '*
  427.                '* Delete the current line in the file
  428.                '*
  429.                CALL DeleteCurrentLine(Index)
  430.                CALL MoveCursor(RowSave, ColSave)
  431. 'CALL UpdatePos
  432.  
  433. 680         CASE CharDeleteKey
  434.                '*
  435.                '* Delete the current character
  436.                '*
  437.                IF CurrentCol <= LEN(ZOutTxt$(Index)) THEN
  438.                   CALL MoveCursor(CurrentRow, CurrentCol + 1)
  439.                   CALL BackspChar
  440. 'CALL UpdatePos
  441.                END IF
  442.  
  443. 690         CASE BackspKey, OtherBackspKey
  444.                '*
  445.                '* Back up one character and destroy it
  446.                '*
  447.                CALL BackspChar
  448. 'CALL UpdatePos
  449.  
  450. 700         CASE CarrRet
  451.                '*
  452.                '* Move to the next line, left column
  453.                '*
  454.                IF NOT Index >= ZMaxMsgLines THEN
  455.                   CALL CarrRetKey
  456. 'CALL UpdatePos
  457.                END IF
  458.  
  459. 710         CASE HelpKey, ReformTextKey, ReflowTextKey, ToggleINSKey, RepaintKey
  460.                '*
  461.                '* Execute a main menu command
  462.                '*
  463.                '*          1234567890123456789012
  464.                YY$ = MID$(" J           HRP     I", KeyPressed, 1)
  465.                CALL MenuCommand(YY$): GOSUB 740
  466.                CALL MoveCursor(RowSave, ColSave)
  467.             CASE IS > 127, IS < 32
  468.                '*
  469.                '* Ignore characters above 127 or below 32
  470.                '*
  471. 720         CASE ELSE
  472.                '*
  473.                '* Input was a normal character
  474.                '*
  475.                CALL NormalChar(B$)
  476.  
  477.          END SELECT
  478.       WEND
  479.  
  480. 730   REDIM ZWorkAra$(13)
  481.       ZHiLiteOff = HiLiteSave
  482.       ZUseTput = UseTputSave
  483.       S$ = MsgSubj$                                                   'RT062992
  484.       CALL AllCaps(S$)                                                'RT062992
  485.       EXIT SUB
  486.  
  487.       '*
  488.       '* Test ZSubParm and Exit ANSIED if the carrier dropped
  489.       '*
  490. 740   IF ZSubParm <> 0 THEN
  491.          GOTO 730
  492.       END IF
  493.       RETURN
  494.  
  495.       END SUB         ' Sub AnsiEd
  496.  
  497. '*  BackspChar()
  498. '*----------------------------------------------------------------------------
  499. '*  This routine handles the user entering the backspace key
  500. '*
  501. '*
  502.       SUB BackspChar STATIC
  503. 1200  CALL SaveCursor(RowSave, ColSave)
  504.       Index = TopLine + CurrentRow - 3
  505.       IF Index = MsgLockLines + 1 AND CurrentCol = 1 THEN
  506.          EXIT SUB
  507.       END IF
  508.       AtEndOfLine = CurrentCol > LEN(ZOutTxt$(Index))
  509. 1210  IF CurrentCol > 1 THEN
  510.          ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 2) + MID$(ZOutTxt$(Index), CurrentCol)
  511.          CALL EraseToEOL(CurrentRow, CurrentCol - 1)
  512.          IF NOT AtEndOfLine THEN
  513.             YY$ = MID$(ZOutTxt$(Index), ColSave - 1)
  514.             CALL MoveCursor(RowSave, ColSave - 1)
  515.             CALL PutScreen(YY$, YellowFore, ZTrue)
  516.          END IF
  517.          CALL MoveCursor(RowSave, ColSave - 1)
  518.          ZWorkAra$(CurrentRow) = ZOutTxt$(Index)
  519.       ELSEIF LEN(ZOutTxt$(Index - 1)) >= ZRightMargin THEN
  520.          '*
  521.          '* Do nothing
  522.          '*
  523. 1220  ELSE
  524.          NewCol = LEN(ZOutTxt$(Index - 1)) + 1
  525.          YY$ = ZOutTxt$(Index)
  526.          CALL UnString(YY$, SoftSpace$)
  527.          ZOutTxt$(Index - 1) = ZOutTxt$(Index - 1) + YY$
  528.                                    ' v2.44a
  529.          IF LEN(ZOutTxt$(Index - 1)) <= ZRightMargin THEN
  530.             CALL DeleteCurrentLine(Index)
  531. 1230     ELSE
  532.             CALL FindWrap(LEFT$(ZOutTxt$(Index - 1), ZRightMargin + 1), I)
  533.             IF I <= 1 THEN
  534.                I = ZRightMargin
  535.             END IF
  536.             ZOutTxt$(Index) = MID$(ZOutTxt$(Index - 1), I + 1)
  537.             ZOutTxt$(Index - 1) = LEFT$(ZOutTxt$(Index - 1), I)
  538.          END IF
  539.          IF RowSave > 3 THEN
  540.             CALL MoveCursor(RowSave - 1, NewCol)
  541.             CALL UpdateScreen
  542.          ELSE
  543.             CALL MoveCursor(RowSave, NewCol)
  544.             CALL UnGetChar(LineUpKey)
  545.          END IF
  546.       END IF
  547.       END SUB
  548.  
  549. '*  CarrRetKey()
  550. '*----------------------------------------------------------------------------
  551. '*  This routine handles carriage returns entered in the file
  552. '*
  553. '*
  554.       SUB CarrRetKey STATIC
  555. 1300  Index = CurrentRow + TopLine - 3
  556.       IF Index >= 99 THEN
  557.          EXIT SUB
  558.       END IF
  559.       IF InsertMode THEN         ' Insert a new line
  560.          FOR I = 98 TO Index + 1 STEP -1
  561.             ZOutTxt$(I + 1) = ZOutTxt$(I)
  562.          NEXT I
  563.          IF LEN(ZOutTxt$(Index)) >= CurrentCol THEN
  564.             ZOutTxt$(Index + 1) = MID$(ZOutTxt$(Index), CurrentCol)
  565.             ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 1)
  566.          ELSE
  567.             ZOutTxt$(Index + 1) = BlankLine$
  568.          END IF
  569.          CALL UpdateScreen
  570. END IF
  571.  
  572.      IF CurrentRow < 19 THEN
  573.         CALL MoveCursor(CurrentRow + 1, 1)
  574.      ELSE
  575.          CALL MoveCursor(CurrentRow,1)
  576.          CALL UnGetChar(LineDownKey)
  577.      END IF
  578.       END SUB
  579.  
  580. '*  ChangeSubject()
  581. '*----------------------------------------------------------------------------
  582. '*  Routine to allow user to change the message subject
  583. '*
  584. '*
  585.       SUB ChangeSubject STATIC
  586.       CALL GetString("Change Subject From '" + MsgSubj$ + "' To? ", NewSubj$)
  587.       IF NewSubj$ <> "" THEN
  588.          MsgSubj$ = LEFT$(NewSubj$, 25)
  589.          CALL NameCaps(MsgSubj$)
  590.       END IF
  591.       END SUB
  592.  
  593. '*  ClearScreen()
  594. '*----------------------------------------------------------------------------
  595. '*  This routine clears the screen and moves the cursor to row 2, col 1
  596. '*
  597. '*
  598.       SUB ClearScreen STATIC
  599. 1500  FOR I = 1 TO 19
  600.          ZWorkAra$(I) = BlankLine$
  601.       NEXT I
  602.       CALL QuickTput("", 0)
  603.       ZSubParm = 2
  604.       CALL Line25
  605.       ZSubParm = 0
  606.       CALL QuickTput("H" + ZEmphasizeOff$, 0)
  607.       CurrentCol = 1
  608.       CurrentRow = 4
  609.       IsBold = DefaultBold
  610.       OldColour = DefaultColor
  611.       END SUB
  612.  
  613. '*  DeleteCurrentLine()
  614. '*----------------------------------------------------------------------------
  615. '*  This routine deletes the current line on the screen and in the array
  616. '*  ZOutTxt$, and moves the next lower line up one  It then repaints the
  617. '*  affected portion of the screen (from the deleted line down)
  618. '*
  619. '*
  620.       SUB DeleteCurrentLine (Index%) STATIC
  621. 1600  FOR I = Index% TO 98
  622.          ZOutTxt$(I) = ZOutTxt$(I + 1)
  623.       NEXT I
  624.       ZOutTxt$(99) = BlankLine$
  625.       CALL UpdateScreen
  626.       END SUB
  627.  
  628. '*  DisplayMainMenu()
  629. '*----------------------------------------------------------------------------
  630. '*  This routine displays the main menu on the top line
  631. '*
  632. '*
  633.       SUB DisplayMainMenu STATIC
  634. 1700  CALL MoveCursor(1, 1)
  635.       YY$ = "A)bort H)elp D)elete I)ns/ovw J)ustify "
  636.       IF ZLocalUser OR ZSysop THEN
  637.          YY$ = YY$ + "O)import R)eflow P)aint S)ave U)subject "
  638.       ELSE
  639.          YY$ = YY$ + "R)eflow P)aint S)ave U)subject          "
  640.       END IF
  641.       CALL ColorPrompt(YY$)
  642.       CALL PutScreen(YY$, DefaultColor, DefaultBold)
  643.       END SUB
  644.  
  645. '*  DoneWithMsg()
  646. '*----------------------------------------------------------------------------
  647. '*  This routine is called to save or abort the message
  648. '*
  649. '*
  650.       SUB DoneWithMsg (YY$) STATIC
  651. 1810  SELECT CASE YY$
  652.          CASE "S"        ' Save Message
  653.             '*
  654.             '* Remove trailing blank lines from the message
  655.             '*
  656.             CALL FindEndOfMsg(EndOfMsg)
  657.             FOR I = 1 TO EndOfMsg
  658.                J = INSTR(ZOutTxt$(I), SoftSpace$)
  659.                WHILE J <> 0
  660.                   MID$(ZOutTxt$(I), J, 1) = " "
  661.                   J = INSTR(ZOutTxt$(I), SoftSpace$)
  662.                WEND
  663.                CALL TrimTrail(ZOutTxt$(I), " ")
  664.             NEXT I
  665.             CALL FindEndOfMsg(ZLinesInMsg)
  666.              CALL EraseToEOL(1, 1)
  667.               CALL MoveCursor(1, 1)
  668.       CALL PutScreen(" ", DefaultColor, DefaultBold)
  669.       CALL ClearScreen                 'Pe 03/15/92
  670.                ZSubParm = 1
  671.  
  672. 1820     CASE "A"
  673.             CALL EraseToEOL(1, 1)
  674.             YY$ = "Abort: Are You Sure (Y)es,[N]o)? "
  675.             CALL ColorPrompt(YY$)
  676.             CALL PutScreen(YY$, DefaultColor, DefaultBold)
  677.             CALL GetChar(B$)
  678.             IF ZSubParm <> 0 THEN
  679.                B$ = "Y"
  680.             END IF
  681.             CALL AllCaps(B$)                                           'RT062992
  682.             IF B$ = "Y" THEN                                           'RT062992
  683.                CALL ClearScreen
  684.                ZSubParm = 2
  685.             END IF
  686.       END SELECT
  687.       END SUB
  688.  
  689. '*  EraseToEOL()
  690. '*----------------------------------------------------------------------------
  691. '*  This routine clears from a position to to the end of that line
  692. '*
  693. '*
  694.       SUB EraseToEOL (LineNumber, ColNumber) STATIC
  695. 1900  CALL MoveCursor(LineNumber, ColNumber)
  696. 'CALL UpdatePos
  697.       CALL QuickTput("", 0)
  698.       END SUB
  699.  
  700. '*  FindEndOfMsg()
  701. '*----------------------------------------------------------------------------
  702. '*  Finds the last active line in the message
  703. '*
  704. '*
  705.       SUB FindEndOfMsg (EndOfMsg) STATIC
  706.       EndOfMsg = 1
  707.       FOR I = ZMaxMsgLines TO 1 STEP -1
  708.          IF ZOutTxt$(I) <> BlankLine$ OR I <= MsgLockLines THEN
  709.             EndOfMsg = I
  710.             EXIT FOR
  711.          END IF
  712.       NEXT I
  713.       END SUB
  714.  
  715. '*  FindWrap()
  716. '*----------------------------------------------------------------------------
  717. '*  This routine finds a place in the string yy$ that could be used as a
  718. '*  place to wrap the line WhereToWrap should be the last position that
  719. '*  remains in the line, ie
  720. '*    set   currentline$ = left$(yy$,wheretowrap)
  721. '*          nextline$    = mid$ (yy$,wheretowrap+1)
  722. '*
  723. '*
  724.       SUB FindWrap (YY$, WhereToWrap) STATIC
  725. 2100  WhereToWrap = LEN(YY$) + 1
  726.       CALL FindWord(YY$, 0, WhereToWrap)
  727.       WhereToWrap = WhereToWrap - 1
  728.       END SUB
  729.  
  730. '*  GetChar()
  731. '*----------------------------------------------------------------------------
  732. '*  This routine reads a character from the user into YY$
  733. '*
  734. '*
  735.       SUB GetChar (YY$) STATIC
  736. 2200  ZAutoLogoff! = TIMER + ZWaitBeforeDisconnect
  737.       CALL Carrier
  738.       YY$ = ""
  739.       WHILE ZSubParm <> -1 AND ZSubParm <> -2 AND YY$ = ""
  740.          ZSubParm = 0
  741.          IF LEN(ZCommportStack$) > 0 THEN
  742.             YY$ = LEFT$(ZCommportStack$, 1)
  743.             ZCommportStack$ = MID$(ZCommportStack$, 2)
  744.          ELSE
  745.             IF ZLocalUser THEN
  746.                YY$ = INKEY$
  747.                IF LEN(YY$) = 2 THEN
  748.                   KeyPressed = ASC(RIGHT$(YY$, 1))
  749.                   YY$ = ""
  750.                   SELECT CASE KeyPressed
  751.                      CASE 82                  ' Insert
  752.                         KeyPressed = ToggleINSKey
  753.                      CASE 83                  ' Delete
  754.                         KeyPressed = CharDeleteKey
  755.                      CASE 71                  ' Home
  756.                         KeyPressed = HomeKey
  757.                      CASE 73                  ' PgUp
  758.                         KeyPressed = PageUpKey
  759.                      CASE 72                  ' Up Arrow
  760.                         KeyPressed = LineUpKey
  761.                      CASE 80                  ' Down Arrow
  762.                         KeyPressed = LineDownKey
  763.                      CASE 81                  ' PgDn
  764.                         KeyPressed = PageDownKey
  765.                      CASE 75                  ' Left Arrow
  766.                         KeyPressed = ColLeftKey
  767.                      CASE 77                  ' Right Arrow
  768.                         KeyPressed = ColRightKey
  769.                      CASE 115                 ' Ctrl-Left Arrow
  770.                         KeyPressed = WordLeftKey
  771.                      CASE 116                 ' Ctrl-Right Arrow
  772.                         KeyPressed = WordRightKey
  773.                      CASE 79                  ' End
  774.                         KeyPressed = EndKey
  775.                      CASE 9
  776.                         KeyPressed = TabKey
  777.                      CASE ELSE
  778.                         KeyPressed = 0
  779.                   END SELECT
  780.                   IF KeyPressed <> 0 THEN
  781.                      YY$ = CHR$(KeyPressed)
  782.                   END IF
  783.                END IF
  784.             ELSE
  785.                CALL FindFKey
  786.                IF ZSubParm >= 0 THEN
  787.                   YY$ = ZKeyPressed$
  788.                   IF YY$ = "" THEN
  789.                      CALL EofComm(Char%)
  790.                      IF Char% = -1 THEN
  791.                         CALL CheckTime(ZAutoLogoff!, Remain!, 1)
  792.                         IF Remain! < 0 THEN
  793.                            CALL UpdtCalr("Sleep disconnect", 1)
  794.                            ZSubParm = -2
  795.                            ZNo = ZTrue
  796.                            ZSleepDisconnect = ZTrue
  797.                         END IF
  798.                      ELSE
  799.                         CALL Carrier
  800.                         IF ZSubParm <> -1 THEN
  801.                            ZSubParm = 0
  802.                            CALL GetCom(YY$)
  803.                         END IF
  804.                      END IF
  805.                   END IF
  806.                END IF
  807.             END IF
  808.          END IF
  809.       WEND
  810.       END SUB
  811.  
  812. '*  GetString()
  813. '*----------------------------------------------------------------------------
  814. '*  Gets a string from the user
  815. '*
  816. '*
  817.       SUB GetString (Prompt$, YY$) STATIC
  818.       YY$ = ""
  819.       CALL EraseToEOL(1, 1)
  820.       CALL PutScreen(Prompt$, DefaultColor, DefaultBold)
  821.       NewCol = CurrentCol
  822.       InitCol = NewCol
  823.       DO
  824.          CALL MoveCursor(CurrentRow, NewCol)
  825.          CALL GetChar(B$)
  826.          IF ZSubParm <> 0 THEN
  827.             B$ = CHR$(ESCKey)
  828.          END IF
  829.          KeyPressed = ASC(B$)
  830.          SELECT CASE KeyPressed
  831.             CASE BackspKey, OtherBackspKey
  832.                IF NewCol <> InitCol THEN
  833.                   CALL MoveCursor(CurrentRow, NewCol - 1)
  834.                   CALL PutScreen(" ", DefaultColor, DefaultBold)
  835.                   NewCol = NewCol - 1
  836.                   YY$ = LEFT$(YY$, LEN(YY$) - 1)
  837.                END IF
  838.             CASE CarrRet
  839.                EXIT DO
  840.             CASE ESCKey
  841.                YY$ = ""
  842.                EXIT DO
  843.             CASE ELSE
  844.                YY$ = YY$ + B$
  845.                CALL PutScreen(B$, DefaultColor, DefaultBold)
  846.                NewCol = NewCol + 1
  847.          END SELECT
  848.       LOOP WHILE 1
  849.       END SUB
  850.  
  851. '*  HelpMe()
  852. '*----------------------------------------------------------------------------
  853. '*  This routine provides on-line help for the user
  854. '*
  855. '*
  856.       SUB HelpMe STATIC
  857. 2300  CALL SaveCursor(RowSave, ColSave)
  858.       CALL ClearScreen
  859.       CALL BufFile(ZHelpPath$ + "ANSIED" + ZHelpExtension$, X)
  860.       CALL ClearScreen
  861.       CALL UpdateScreen
  862.       CALL MoveCursor(RowSave, ColSave)
  863.       END SUB
  864.  
  865. '*  ImportFile()
  866. '*----------------------------------------------------------------------------
  867. '*  Imports an ASCII text file in the message
  868. '*
  869. '*
  870.       SUB ImportFile STATIC
  871.       IF ZLocalUser OR ZSysop THEN
  872.          CALL GetString("Import What File? ", FileName$)
  873.          IF FileName$ <> "" THEN
  874.             CALL FindIt(FileName$)
  875.             IF ZOK THEN
  876.                ZUserIn$(1) = FileName$
  877.                ZAnsIndex = 0
  878.                ZLastIndex = 1
  879.                CALL FindEndOfMsg(EndOfMsg)
  880.                CALL MsgImport(ZMaxMsgLines, ZRightMargin, EndOfMsg, ZOutTxt$())
  881.          J = EndOfMsg \ 11
  882.          IF EndOfMsg MOD 11 = 0 THEN
  883.            J = J - 1
  884.          END IF
  885.           TopLine = J * 11 + 1
  886.            J = EndOfMsg - TopLine
  887.           CALL MoveCursor(J + 5, 1)
  888.          CALL UpdateScreen
  889.             END IF
  890.          END IF
  891.       END IF
  892.       END SUB
  893.  
  894. '*  LastParaLine()
  895. '*----------------------------------------------------------------------------
  896. '*  This routine returns ZTrue if ZOutTxt$(I) is the last line
  897. '*  in a paragraph
  898. '*
  899. '*
  900.       SUB LastParaLine (I, LastLine, Result) STATIC
  901. 2400  Result = ZFalse
  902.       IF I = LastLine OR I >= ZMaxMsgLines THEN
  903.          Result = ZTrue
  904.       ELSE
  905.          YY$ = ZOutTxt$(I)
  906.          J = INSTR(YY$, ">")
  907.          IF J = 0 THEN
  908.             J = 6
  909.          END IF
  910.          IF J < 5 THEN
  911.             Result = ZTrue
  912.          ELSEIF YY$ = BlankLine$ THEN
  913.             Result = ZTrue
  914.          ELSE
  915.             IF ZOutTxt$(I + 1) = BlankLine$ THEN
  916.                Result = ZTrue
  917.             ELSEIF LEFT$(ZOutTxt$(I + 1), 1) = " " THEN
  918.                Result = ZTrue
  919.             ELSE
  920.                K = INSTR(ZOutTxt$(I + 1), ">")
  921.                IF K <> 0 AND K < 5 THEN
  922.                   Result = ZTrue
  923.                END IF
  924.             END IF
  925.          END IF
  926.       END IF
  927.       END SUB
  928.  
  929. '*  MenuCommand()
  930. '*----------------------------------------------------------------------------
  931. '* This routine executes the passed main menu command
  932. '*
  933. '*
  934.       SUB MenuCommand (YY$) STATIC
  935. 2450  ZSubParm = 0              ' v2.44a
  936.       SELECT CASE YY$
  937. '         CASE "+"
  938. '         CASE "-"
  939.          CASE "H"
  940.             CALL HelpMe
  941.             CALL DisPlayKeys       'Pe 03/17/92
  942.          CASE "S", "A"
  943.             CALL DoneWithMsg(YY$)
  944.          CASE "P"
  945.             CALL ClearScreen
  946.             CALL DisplayKeys
  947.             CALL UpdateScreen
  948.          CASE "I"
  949.             InsertMode = NOT InsertMode
  950.          CASE "R"
  951.             CALL ReformText(ZFalse)
  952.          CASE "J"
  953.             CALL ReformText(ZTrue)
  954.          CASE "O"
  955.             CALL ImportFile
  956.          CASE "U"
  957.             CALL ChangeSubject
  958.       END SELECT
  959.       IF ZSubParm = 0 THEN
  960.          CALL EraseToEOL(1, 1)
  961.          CALL UpdateStatusLine(1)
  962.       END IF
  963.       END SUB
  964.  
  965. '*  MoveCursor()
  966. '*----------------------------------------------------------------------------
  967. '*  This routine moves the cursor to the position spec'd by newcol and
  968. '*  newrow and tries to do it with the minimum number of Ansi characters
  969. '*
  970. '*
  971.       SUB MoveCursor (NewRow, NewCol) STATIC
  972. 2500  YY$ = "        "
  973.       CALL MoveCurStr(CurrentRow, CurrentCol, NewRow, NewCol, YY$, YLen)
  974.       IF YLen <> 0 THEN
  975.          YY$ = LEFT$(YY$, YLen)
  976.          CALL QuickTput(YY$, 0)
  977.       END IF
  978.       ZSubParm = 0
  979.       END SUB
  980.  
  981. '*  NormalChar()
  982. '*----------------------------------------------------------------------------
  983. '*  This routine handles 'normal' characters entered into the message
  984. '*
  985. '*
  986.       SUB NormalChar (YY$) STATIC
  987.  
  988. 2600  CALL SaveCursor(RowSave, ColSave)
  989.       Index = CurrentRow + TopLine - 3
  990.       CurrentLineBlank = (ZOutTxt$(Index) = BlankLine$)
  991.       LML = LEN(ZOutTxt$(Index))
  992.  
  993.       IF CurrentCol > 79 THEN
  994.          EXIT SUB
  995.       END IF
  996.  
  997.       AtEndOfLine = ZFalse
  998.  
  999.       IF CurrentCol > LML THEN
  1000.          ZOutTxt$(Index) = ZOutTxt$(Index) + SPACE$(CurrentCol - LML)
  1001.          ZWorkAra$(CurrentRow) = ZWorkAra$(CurrentRow) + SPACE$(CurrentCol - LML)
  1002.          LML = LEN(ZOutTxt$(Index))
  1003.          AtEndOfLine = ZTrue
  1004.       END IF
  1005.  
  1006. 2610  IF (CurrentCol <= ZRightMargin AND AtEndOfLine) OR (CurrentCol <= ZRightMargin AND NOT InsertMode) THEN
  1007.          '*
  1008.          '* Single character changed
  1009.          '*
  1010.          MID$(ZOutTxt$(Index), CurrentCol, 1) = YY$
  1011.          MID$(ZWorkAra$(CurrentRow), CurrentCol, 1) = YY$
  1012.          CALL PutScreen(YY$, YellowFore, ZTrue)
  1013.                                                                                     ' v2.44a
  1014. 2620  ELSEIF (NOT AtEndOfLine AND InsertMode AND CurrentCol <= ZRightMargin AND LML < ZRightMargin) THEN
  1015.          '*
  1016.          '* Have to rewrite the screen from the current pos forward
  1017.          '*
  1018.          ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 1) + YY$ + MID$(ZOutTxt$(Index), CurrentCol)
  1019.  
  1020.          ZWorkAra$(CurrentRow) = ZOutTxt$(Index)
  1021.  
  1022.          CALL EraseToEOL(CurrentRow, CurrentCol)
  1023.          ZZ$ = MID$(ZWorkAra$(CurrentRow), CurrentCol)
  1024.          CALL PutScreen(ZZ$, YellowFore, ZTrue)
  1025.          CALL MoveCursor(RowSave, ColSave + 1)
  1026.  
  1027. 2630  ELSE
  1028.          '*
  1029.          '* Wrap the end of the line
  1030.          '*
  1031.          IF NOT AtEndOfLine THEN
  1032.             ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), CurrentCol - 1) + YY$ + MID$(ZOutTxt$(Index), CurrentCol)
  1033.             LML = LML + 1
  1034.          ELSE
  1035.             MID$(ZOutTxt$(Index), CurrentCol, 1) = YY$
  1036.          END IF
  1037.  
  1038.          CALL FindWrap(ZOutTxt$(Index), I)
  1039.          IF I <= 1 THEN
  1040.             I = ZRightMargin
  1041.          END IF
  1042.  
  1043.          ZZ$ = MID$(ZOutTxt$(Index), (I + 1))
  1044.          CALL TrimTrail(ZZ$, SoftSpace$)
  1045.          ZOutTxt$(Index) = LEFT$(ZOutTxt$(Index), I)
  1046.          '*
  1047.          '* Add to the beginning of a new line
  1048.          '*
  1049.          IF Index <= 98 THEN
  1050.             Index = Index + 1
  1051.          END IF
  1052.  
  1053.          Z = INSTR(ZOutTxt$(Index), ">")                                                  ' v2.44a
  1054.          IF ZOutTxt$(Index) <> BlankLine$ AND (Z <= 0 OR Z > 6) AND LEN(ZOutTxt$(Index)) + LEN(ZZ$) < ZRightMargin THEN
  1055.             ZOutTxt$(Index) = ZZ$ + ZOutTxt$(Index)
  1056.          ELSE
  1057.             FOR J = 98 TO Index STEP -1
  1058.                ZOutTxt$(J + 1) = ZOutTxt$(J)
  1059.             NEXT J
  1060.             ZOutTxt$(Index) = ZZ$
  1061.          END IF
  1062.  
  1063.          CALL EraseToEOL(CurrentRow, I + 1)        ' do the "easy" line
  1064.          ZWorkAra$(CurrentRow) = ZOutTxt$(Index)
  1065.  
  1066.          CALL UpdateScreen
  1067.          IF (ColSave > I) THEN
  1068.             NewCol = ColSave - I + 1
  1069.             IF RowSave <> 19 THEN
  1070.                CALL MoveCursor(RowSave + 1, NewCol)
  1071.             ELSE
  1072.                CALL MoveCursor(RowSave, NewCol)
  1073.                CALL UnGetChar(LineDownKey)
  1074.             END IF
  1075.          ELSE
  1076.             CALL MoveCursor(RowSave, ColSave + 1)
  1077.          END IF
  1078.       END IF
  1079. 'CALL UpdatePos
  1080.       END SUB
  1081.  
  1082. '*  PutScreen()
  1083. '*----------------------------------------------------------------------------
  1084. '* This routine writes YY$ to the user in the color and
  1085. '* intensity specified
  1086. '*
  1087. '*
  1088.       SUB PutScreen (YY$, Colour, Bold) STATIC
  1089. 2800  ZZ$ = ""
  1090.       IF Colour <> 99 THEN
  1091.          IF (Colour <> OldColour) OR (Bold <> IsBold) THEN
  1092.             ZZ$ = ""
  1093.             IF Bold <> IsBold THEN
  1094.                IF Bold THEN
  1095.                   ZZ$ = ZZ$ + "1;"
  1096.                ELSE
  1097.                   ZZ$ = ZZ$ + "0;"
  1098.                END IF
  1099.             END IF
  1100.             ZZ$ = ZZ$ + MID$(STR$(Colour), 2) + "m"
  1101.          END IF
  1102.       ELSE
  1103.          ZZ$ = ZEmphasizeOff$
  1104.       END IF
  1105.       ZOutTxt$ = ZZ$ + YY$
  1106.       IF ZLocalUser THEN
  1107.          CALL QuickTput(ZOutTxt$, 0)
  1108.       ELSE
  1109.          ZSubParm = 4
  1110.          CALL Tput
  1111.       END IF
  1112.       ZSubParm = 0
  1113.       IF INSTR(YY$, "") = 0 THEN
  1114.          CurrentCol = CurrentCol + LEN(YY$)
  1115.          IF CurrentCol > 80 THEN
  1116.             CurrentCol = 0
  1117.             CurrentRow = 0
  1118.          END IF
  1119.       ELSE
  1120.          CurrentRow = 0
  1121.          CurrentCol = 0
  1122.       END IF
  1123.       OldColour = Colour
  1124.       IsBold = Bold
  1125.       END SUB
  1126.  
  1127. '*  ReformText()
  1128. '*----------------------------------------------------------------------------
  1129. '*  This routine reflows the text to the current margins.  Optionally,
  1130. '*  it right justifies all lines by adding "soft spaces"
  1131. '*
  1132. '*
  1133.       SUB ReformText (Justify%) STATIC
  1134.  
  1135. 2900  DIM Places(80)
  1136.  
  1137.       CALL EraseToEOL(1, 1)
  1138.       CALL PutScreen("Reformatting... Please Wait.", WhiteFore, ZTrue)
  1139.  
  1140.       CALL FindEndOfMsg(EndOfMsg)
  1141.  
  1142.       I = MsgLockLines + 1   ' Read index
  1143.       J = MsgLockLines + 1   ' Write index
  1144.  
  1145.       '*
  1146.       '* Reflow the text to the maximum on a line
  1147.       '*
  1148.       DO WHILE I <= EndOfMsg
  1149.          '*
  1150.          '* Loop until we get a long line or an end of paragraph
  1151.          '*
  1152.          ZOutTxt$ = ""
  1153.          DO WHILE 1
  1154.             YY$ = ZOutTxt$(I)
  1155.             CALL UnString(YY$, SoftSpace$)
  1156.             IF ZOutTxt$ <> "" AND RIGHT$(ZOutTxt$, 1) <> " " THEN
  1157.                ZOutTxt$ = ZOutTxt$ + " "
  1158.             END IF
  1159.             ZOutTxt$ = ZOutTxt$ + YY$
  1160.             CALL LastParaLine(I, EndOfMsg, EndOfPara)
  1161.             I = I + 1
  1162.             IF LEN(ZOutTxt$) > ZRightMargin THEN
  1163.                '*
  1164.                '* Wrap the long line
  1165.                '*
  1166.                CALL FindWrap(LEFT$(ZOutTxt$, ZRightMargin + 1), K)
  1167.                IF K <= 1 THEN
  1168.                   K = ZRightMargin
  1169.                END IF
  1170.                ZOutTxt$(J) = LEFT$(ZOutTxt$, K)
  1171.                IF EndOfPara THEN
  1172.                   '*
  1173.                   '* Go to the next paragraph
  1174.                   '*
  1175.                   J = J + 1
  1176.                   ZOutTxt$(J) = MID$(ZOutTxt$, K + 1)
  1177.                ELSE
  1178.                   '*
  1179.                   '* Keep the remaining part of the line and process
  1180.                   '* it on the next pass
  1181.                   '*
  1182.                   I = I - 1
  1183.                   ZOutTxt$(I) = MID$(ZOutTxt$, K + 1)
  1184.                END IF
  1185.                J = J + 1
  1186.                EXIT DO
  1187.             ELSEIF EndOfPara THEN
  1188.                ZOutTxt$(J) = ZOutTxt$
  1189.                J = J + 1
  1190.                EXIT DO
  1191.             END IF
  1192.          LOOP
  1193.       LOOP
  1194.  
  1195.       FOR I = J TO 99
  1196.          ZOutTxt$(I) = BlankLine$
  1197.       NEXT
  1198.  
  1199.       EndOfMsg = J - 1
  1200.  
  1201.       '*
  1202.       '* Space out the text on each line
  1203.       '*
  1204.       IF Justify% THEN
  1205.          FOR I = MsgLockLines + 1 TO EndOfMsg
  1206.             CALL LastParaLine(I, EndOfMsg, EndOfPara)
  1207.             IF NOT EndOfPara THEN
  1208.                '*
  1209.                '* Space out the line
  1210.                '*
  1211.                ZOutTxt$ = ZOutTxt$(I)
  1212.                CALL TrimTrail(ZOutTxt$, " ")
  1213.                TxtLen = LEN(ZOutTxt$)
  1214.                SpacesToAdd = ZRightMargin - TxtLen
  1215.                IF SpacesToAdd > 0 THEN
  1216.                   '*
  1217.                   '* Skip leading spaces on the line
  1218.                   '*
  1219.                   Place = 1
  1220.                   IF LEFT$(ZOutTxt$, 1) = " " THEN
  1221.                      CALL FindWord(ZOutTxt$, 1, Place)
  1222.                   END IF
  1223.                   '*
  1224.                   '* Find all of the possible places to space out the line
  1225.                   '*
  1226.                   NumPlaces = 0
  1227.                   DO WHILE 1
  1228.                      CALL FindWord(ZOutTxt$, 1, Place)
  1229.                      IF Place < TxtLen THEN
  1230.                         NumPlaces = NumPlaces + 1
  1231.                         Places(NumPlaces) = Place
  1232.                      ELSE
  1233.                         EXIT DO
  1234.                      END IF
  1235.                   LOOP
  1236.                   '*
  1237.                   '* Fill in available places with soft spaces
  1238.                   '*
  1239.                   IF NumPlaces <> 0 THEN
  1240.                      ExtraPlaces = (SpacesToAdd MOD NumPlaces)
  1241.                      LeftExtra = ExtraPlaces \ 2
  1242.                      RightExtra = ExtraPlaces - LeftExtra
  1243.                      FOR J = NumPlaces TO 1 STEP -1
  1244.                         SpacesThisPlace = SpacesToAdd \ NumPlaces
  1245.                         IF J <= LeftExtra OR J > NumPlaces - RightExtra THEN
  1246.                            SpacesThisPlace = SpacesThisPlace + 1
  1247.                         END IF
  1248.                         IF SpacesThisPlace <> 0 THEN
  1249.                            ZOutTxt$ = LEFT$(ZOutTxt$, Places(J) - 1) + STRING$(SpacesThisPlace, SoftSpace$) + MID$(ZOutTxt$, Places(J))
  1250.                         END IF
  1251.                      NEXT J
  1252.                   END IF
  1253.                END IF
  1254.                ZOutTxt$(I) = ZOutTxt$
  1255.             END IF
  1256.          NEXT I
  1257.       END IF
  1258.  
  1259.       CALL UpdateScreen
  1260.  
  1261.       END SUB
  1262.  
  1263. '*  SaveCursor()
  1264. '*----------------------------------------------------------------------------
  1265. '*  This routine saves the current cursor position
  1266. '*
  1267. '*
  1268.       SUB SaveCursor (Row%, Col%) STATIC
  1269.       Row% = CurrentRow
  1270.       Col% = CurrentCol
  1271.       END SUB
  1272.  
  1273. '*  UnGetChar()
  1274. '*----------------------------------------------------------------------------
  1275. '*   Puts a key in the beginning of the keyboard buffer
  1276. '*
  1277. '*
  1278.       SUB UnGetChar (X) STATIC
  1279.       ZCommportStack$ = CHR$(X) + ZCommportStack$
  1280.       END SUB
  1281.  
  1282. '*  UnString()
  1283. '*----------------------------------------------------------------------------
  1284. '*  Removes one string from another
  1285. '*
  1286. '*
  1287.       SUB UnString (YY$, BadString$) STATIC
  1288.       I = INSTR(YY$, BadString$)
  1289.       WHILE I <> 0
  1290.          YY$ = LEFT$(YY$, I - 1) + MID$(YY$, I + LEN(BadString$))
  1291.          I = INSTR(YY$, BadString$)
  1292.       WEND
  1293.       END SUB
  1294.  
  1295. '*  UpdateScreen()
  1296. '*----------------------------------------------------------------------------
  1297. '*  This is one of the most important routines  It compares the arrays
  1298. '*  ZOutTxt$ and ZWorkAra$ and only sends the user the DIFFERENCE between the
  1299. '*  two within the viewing area  In this way all processing can be done on
  1300. '*  ZOutTxt$ and then the screen is updated to reflect the changes. After the
  1301. '*  users screen is updated, ZWorkAra$ is changed to reflect what should be
  1302. '*  on the users' screen The cursor is restored to its original position
  1303. '*
  1304. '*
  1305.       SUB UpdateScreen STATIC
  1306. 3100  CALL SaveCursor(Row, Col)
  1307.       FOR I = 3 TO 19
  1308.          Index = I + TopLine - 3
  1309.          ScreenLine$ = ZWorkAra$(I)
  1310.          MessageLine$ = ZOutTxt$(Index)
  1311.          LML = LEN(MessageLine$)
  1312.  
  1313.          IF Index = ZMaxMsgLines + 1 THEN
  1314.             CALL EraseToEOL(I, 1)
  1315.             CALL PutScreen("[* End of Message *]", CyanFore, ZFalse)
  1316.             ZWorkAra$(I) = CHR$(EndKey)
  1317.          ELSEIF Index > ZMaxMsgLines + 1 THEN
  1318.             IF ScreenLine$ <> BlankLine$ THEN
  1319.                CALL EraseToEOL(I, 1)
  1320.                ZWorkAra$(I) = BlankLine$
  1321.             END IF
  1322.          ELSEIF MessageLine$ = ScreenLine$ THEN
  1323.             '*
  1324.             '* Screen = What's in message buffer
  1325.             '*
  1326.          ELSEIF MessageLine$ = BlankLine$ OR MessageLine$ = SPACE$(LML) THEN
  1327.             CALL EraseToEOL(I, 1)
  1328.             ZWorkAra$(I) = MessageLine$
  1329.          ELSE
  1330.           CALL MoveCursor(I, 1)
  1331.           YY$ = MessageLine$
  1332.           CALL EraseToEOL(CurrentRow, CurrentCol) ' <-- Switched these 2 to
  1333.           CALL PutScreen(YY$, YellowFore, ZTrue)  ' <-- get P)aint Working
  1334.           ZWorkAra$(I) = ZOutTxt$(Index)          '     Properly.
  1335.          END IF
  1336.       NEXT I
  1337.     CALL MoveCursor(Row,Col)
  1338.       END SUB
  1339.  
  1340. '*
  1341. '* UpdatePos
  1342. '* Updates Current Cursor Row and Position
  1343. '* on Screen in Upper right hand corner.
  1344. '*
  1345.  
  1346. SUB UpdatePos STATIC
  1347. CALL SaveCursor(RowSave, ColSave)
  1348.  CALL MoveCursor (2,74)
  1349.   CALL PutScreen(STR$(RowSave) + " ",GreenFore,ZTrue)
  1350.    CALL MoveCursor (2,77)
  1351.     CALL PutScreen(STR$(ColSave)+ " ",RedFore,ZTrue)
  1352.      CALL MoveCursor(RowSave, ColSave)
  1353. END SUB
  1354.  
  1355. '*  UpdateStatusLine()
  1356. '*-----------------------------------------------------------------------------
  1357. '*  Rewrites the status line on screen line(s) 1 and 2
  1358. '*
  1359. '*    Input:  How% = 1   - Rewrite both lines
  1360. '*            How% = 2   - Just rewrite top line
  1361. ' Changed this a little bit.
  1362. ' Changed the DOUBLE ESC command to CTRL-K (Double ESC still works)
  1363. ' CTRL-K was easier to explain to brain dead users :)
  1364. ' Also attempted to make CTRL-K stand out a bit more
  1365. '
  1366.  
  1367.       SUB UpdateStatusLine (How%) STATIC
  1368. 3200  CALL MoveCursor(1, 1)
  1369.       CALL PutScreen("ANSIED " + Version$ +" by Tom Collins       ", BlueFore, ZTrue)
  1370.       CALL PutScreen("Hit Esc Twice or Cntrl-K ",RedFore, ZTrue)
  1371.       CALL PutScreen("for Menu" + SPACE$(24),BlueFore, ZTrue)
  1372.  
  1373. 3210  IF How% = 1 THEN
  1374.          YY$ = CHR$(205) + " To: " + MsgTo$ + " " + CHR$(205) + " Re: " + MsgSubj$ + " " + CHR$(205)
  1375.          YY$ = YY$ + STRING$(74 - LEN(YY$), CHR$(205))
  1376.          IF InsertMode THEN
  1377.             MID$(YY$, 70) = " Ins "
  1378.          ELSE
  1379.             MID$(YY$, 70) = " Ovw "
  1380.          END IF
  1381.          I = 1
  1382.          CALL MoveCursor(2, I)
  1383.          CALL PutScreen(YY$, WhiteFore, ZFalse)
  1384.       END IF
  1385.       END SUB
  1386.  
  1387. 3220 SUB DisplayKeys STATIC
  1388.   CALL MoveCursor(20,1)
  1389. YY$ = STRING$(79,CHR$(205))
  1390. MID$ (YY$,30) = "ANSIED QuickKeys Menu"
  1391.   CALL Putscreen(YY$,RedFore,DefaultBold)
  1392.   CALL MoveCursor(21,1)
  1393.   CALL PutScreen ("^A Word Left  ^B Reformat  ^C PageDown  ^D ColRight ^E LineUp   ^F Word Right",DefaultColor, DefaultBold)
  1394.   CALL MoveCursor(22,1)
  1395.   CALL PutScreen ("^G Del        ^O Reflow    ^P Repaint   ^R PageUp   ^S ColLeft  ^T DelWordRight",DefaultColor, DefaultBold)
  1396.   CALL MoveCursor(23,1)
  1397.   CALL PutScreen ("^V Toggle Ins ^W home      ^X Line Down ^Y Del Line ^Z End",DefaultColor, DefaultBold)
  1398.   CALL MoveCursor(24,1)
  1399.   CALL PutScreen ("^K Lists Menu",GreenFore, DefaultBold)
  1400.  
  1401.      END SUB
  1402.